package com.tf_cut.backend.service.service;

import com.netflix.discovery.converters.Auto;
import com.tf_cut.backend.common.pojo.PageInfo;
import com.tf_cut.backend.common.pojo.Result;
import com.tf_cut.backend.common.service.CommonServiceImpl;
import com.tf_cut.backend.mapper.ServiceInfoMapper;
import com.tf_cut.backend.request.DefaultMybankClient;
import com.tf_cut.backend.request.DefaultSigner;
import com.tf_cut.backend.request.MybankApiException;
import com.tf_cut.backend.request.Signer;
import com.tf_cut.backend.seller.service.SellerAccountService;
import com.tf_cut.backend.seller.vo.SellerAndAccountVo;
import com.tf_cut.backend.seller.vo.SellerRegisterMobel;
import com.tf_cut.backend.seller.vo.SellerRegisterQueryMobel;
import com.tf_cut.backend.seller.vo.SellerRegisterVo;
import com.tf_cut.backend.service.pojo.ServiceInfo;
import com.tf_cut.backend.service.repository.ServiceInfoRepository;
import com.tf_cut.backend.service.vo.ServiceInfoVo;
import com.tf_cut.backend.service.vo.ServiceRegisterVo;
import com.tf_cut.backend.util.HttpUtil;
import com.tf_cut.backend.util.MyConfig;
import com.tf_cut.backend.util.SerialNoUtil;

import lombok.extern.slf4j.Slf4j;

import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
@Slf4j
public class ServiceInfoServiceImpl extends CommonServiceImpl<ServiceInfoVo, ServiceInfo, String>
		implements ServiceInfoService {

	@PersistenceContext
	private EntityManager em;
	@Autowired
	private ServiceInfoRepository serviceInfoRepository;
	@Autowired
	private SellerAccountService sellerAccountService;
	@Autowired
	private ServiceInfoMapper serviceInfoMapper;
	@Autowired
	private ServiceRegisterService serviceRegisterService;

	@Resource
	private SerialNoUtil util;

	private static Signer signer = new DefaultSigner(MyConfig.privateKey);

	@Override
	public Result<ServiceInfoVo> insertServiceInfo(ServiceInfoVo svo) {
		Result<ServiceInfoVo> result = this.save(svo);
		result.setData(svo);
		return result;
	}

	@Override
	public PageInfo<ServiceInfoVo> queryServiceInfoList(ServiceInfoVo serviceInfoVo) {
		com.github.pagehelper.PageHelper.startPage(serviceInfoVo.getPage(), serviceInfoVo.getRows());
		List<ServiceInfoVo> list = serviceInfoMapper.findListServiceInfo(serviceInfoVo);
		com.github.pagehelper.PageInfo<ServiceInfoVo> pageInfo = new com.github.pagehelper.PageInfo<>(list);

		PageInfo<ServiceInfoVo> returnPageInfo = new PageInfo<>();
		returnPageInfo.setPage(pageInfo.getPageNum());
		returnPageInfo.setPageSize(pageInfo.getPageSize());
		returnPageInfo.setRows(pageInfo.getList());
		returnPageInfo.setRecords((int) pageInfo.getTotal());
		returnPageInfo.setTotal(pageInfo.getPages());
		return returnPageInfo;
	}

	// 服务商入驻
	@Override
	public ServiceInfoVo register(String serviceId) {
		ServiceInfoVo svo = serviceInfoMapper.findByServiceRegisterRuzhu(serviceId);
		new DefaultMybankClient(MyConfig.serverUrl, MyConfig.privateKey, MyConfig.mybankPublicKey);
		//String serialNo = util.genSerialNo("Y", "A", "3");
		SellerRegisterMobel sellerRegisterMobel = new SellerRegisterMobel();
		sellerRegisterMobel.setIsvOrgId(MyConfig.isvOrgId);
		sellerRegisterMobel.setOutTradeNo(UUID.randomUUID().toString().replace("-", ""));
		sellerRegisterMobel.setOutMerchantId(UUID.randomUUID().toString().replace("-", ""));
		sellerRegisterMobel.setMerchantName(svo.getServiceCom());
		sellerRegisterMobel.setMerchantType("03");
		try {
			sellerRegisterMobel.setMerchantDetail(MyConfig.serviceBase64(svo));
			sellerRegisterMobel.setBankCardParam(MyConfig.Base64Bank(svo));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		sellerRegisterMobel.setDealType("01");
		sellerRegisterMobel.setMainIdentity("CORMANAGEMENT");
		sellerRegisterMobel.setSubIdentity("HR_COR");
		sellerRegisterMobel.setAuthCode("");
		sellerRegisterMobel.setMcc("");
		sellerRegisterMobel.setCloudFundsInfo("");
		sellerRegisterMobel.setIdentityExt("{\"LAB_MODEL\":\"" + "PAYROLL" + "\"}");
		// 采用非注解方式将对象转xml
		String resultXml = MyConfig.beanToXml(sellerRegisterMobel, "ant.mybank.merchantprod.merch.register");
		System.out.println("对象转码" + resultXml);
		try {
			String sellerRegisterVoXml = signer.sign(resultXml, MyConfig.charset, MyConfig.signType);
			String response = HttpUtil.doPosts(MyConfig.serverUrl, sellerRegisterVoXml, "UTF-8");
			System.out.println("服务商入驻返回响应报文：" + response);
			SAXReader reader = new SAXReader();
			try {
				String OutMerchantId = null;
				String OrderNo = null;
				String OutTradeNo = null;
				String resultStatus = null;
				org.dom4j.Document doc = reader.read(new ByteArrayInputStream(response.getBytes("UTF-8")));
				org.dom4j.Element root = doc.getRootElement();
				org.dom4j.Element element;
				org.dom4j.Element element2;
				org.dom4j.Element element3;
				for (Iterator i = root.elementIterator("response"); i.hasNext();) {
					element = (org.dom4j.Element) i.next();

					for (Iterator j = element.elementIterator("body"); j.hasNext();) {
						element2 = (org.dom4j.Element) j.next();
						for (Iterator k = element2.elementIterator("RespInfo"); k.hasNext();) {
							element3 = (org.dom4j.Element) k.next();
							resultStatus = element3.elementText("ResultStatus");
							String resultCode = element3.elementText("ResultCode");
							String resultMsg = element3.elementText("ResultMsg");
							serviceInfoMapper.updateStus(resultStatus, resultCode, resultMsg, svo.getServiceId());
							svo.setResultStatus(resultStatus);
							svo.setResultCode(resultCode);
							svo.setResultMsg(resultMsg);
						}
						OutMerchantId = element2.elementText("OutMerchantId");
						OrderNo = element2.elementText("OrderNo");
						OutTradeNo = element2.elementText("OutTradeNo");
					}
				}
				if (resultStatus.equals("S") || resultStatus.equals("U")) {
					ServiceRegisterVo serviceRegisterVo = new ServiceRegisterVo();
					// if (svo.getRegisterId() != null &&
					// !svo.getRegisterId().equals("")) {
					// sellerAndAccountMapper.updateRegisterStatus(svo.getRegisterId());
					// }
					serviceRegisterVo.setRegisterId(svo.getRegisterId());
					serviceRegisterVo.setStatus("1");
					serviceRegisterVo.setServiceId(svo.getServiceId());
					serviceRegisterVo.setOrderNo(OrderNo);
					serviceRegisterVo.setOutTradeNo(OutTradeNo);
					serviceRegisterVo.setOutMerchantId(OutMerchantId);
					serviceRegisterVo.setRegisterStatus("0");
					serviceRegisterVo.setFailReason("");
					serviceRegisterService.save(serviceRegisterVo);
				}
			} catch (DocumentException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} catch (MybankApiException e) {
			e.printStackTrace();
		}
		return svo;
	}
	
	
	
	/**
	 * 商户入驻查询
	 */
	@Override
	public void registerQuery(String serviceId) {
		ServiceInfoVo svo = serviceInfoMapper.findByServiceRegisterRuzhu(serviceId);
		new DefaultMybankClient(MyConfig.serverUrl, MyConfig.privateKey, MyConfig.mybankPublicKey);
		SellerRegisterQueryMobel sellerRegisterQueryMobel = new SellerRegisterQueryMobel();
		sellerRegisterQueryMobel.setIsvOrgId(MyConfig.isvOrgId);
		sellerRegisterQueryMobel.setOrderNo(svo.getOrderNo());
		// 采用非注解方式将对象转xml
		String resultXml = MyConfig.beanToXml(sellerRegisterQueryMobel, "ant.mybank.merchantprod.merch.register.query");
		System.out.println("对象转码" + resultXml);

		String sellerRegisterVoXml;
		try {
			sellerRegisterVoXml = signer.sign(resultXml, MyConfig.charset, MyConfig.signType);
			String response = HttpUtil.doPosts(MyConfig.serverUrl, sellerRegisterVoXml, "UTF-8");
			System.out.println("商户入驻查询返回响应报文：" + response);
			SAXReader reader = new SAXReader();
			try {
				String OutMerchantId = null;
				String OrderNo = null;
				String OutTradeNo = null;
				String merchantId = null;
				String registerStatus = null;
				String failReason = null;
				org.dom4j.Document doc = reader.read(new ByteArrayInputStream(response.getBytes("UTF-8")));
				org.dom4j.Element root = doc.getRootElement();
				org.dom4j.Element element;
				org.dom4j.Element element2;
				org.dom4j.Element element3;
				for (Iterator i = root.elementIterator("response"); i.hasNext();) {
					element = (org.dom4j.Element) i.next();
					for (Iterator j = element.elementIterator("body"); j.hasNext();) {
						element2 = (org.dom4j.Element) j.next();
						for (Iterator k = element2.elementIterator("RespInfo"); k.hasNext();) {
							element3 = (org.dom4j.Element) k.next();
							String resultStatus = element3.elementText("ResultStatus");
							String resultCode = element3.elementText("ResultCode");
							String resultMsg = element3.elementText("ResultMsg");
							serviceInfoMapper.updateStus(resultStatus, resultCode, resultMsg, svo.getServiceId());
						}
						OutMerchantId = element2.elementText("OutMerchantId");
						OrderNo = element2.elementText("OrderNo");
						OutTradeNo = element2.elementText("OutTradeNo");
						merchantId = element2.elementText("MerchantId");
						registerStatus = element2.elementText("RegisterStatus");
						failReason = element2.elementText("FailReason");
					}
				}
				//String serialNo = util.genSerialNo("Y", "A", "3");
				ServiceRegisterVo serviceRegisterVo = new ServiceRegisterVo();
				serviceRegisterVo.setRegisterId(svo.getRegisterId());
				serviceRegisterVo.setServiceId(svo.getServiceId());
				serviceRegisterVo.setMerchantId(merchantId);
				serviceRegisterVo.setRegisterStatus(registerStatus);
				serviceRegisterVo.setOrderNo(OrderNo);
				serviceRegisterVo.setOutTradeNo(OutTradeNo);
				serviceRegisterVo.setOutMerchantId(OutMerchantId);
				serviceRegisterVo.setFailReason(failReason);
				serviceRegisterVo.setStatus("3");
				serviceRegisterService.save(serviceRegisterVo);
			} catch (DocumentException | UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} catch (MybankApiException e) {
			e.printStackTrace();
		}

	}
}
